package scales.utils.collection
import annotation.tailrec
import scales.utils.Equiv
import scalaz._
import Scalaz._
import scales.utils.collection.array._
trait ArraySetsFactory[A] {
protected def equal: Equal[A]
protected implicit def arrayManifest: ClassManifest[A]
def emptySet: ArraySet[A]
protected def one(a: A): ArraySet[A]
protected def two(a: A, b: A): ArraySet[A]
protected def three(a: A, b: A, c: A): ArraySet[A]
protected def four(a: A, b: A, c: A, d: A): ArraySet[A]
protected def five(a: A, b: A, c: A, d: A, e: A): ArraySet[A]
protected def more(allTheAs: Array[A]): ArraySet[A]
}
object ArraySet {
def factory[A](implicit equalI: Equal[A], arrayManifestI: ClassManifest[A]): ArraySetsFactory[A] = {
trait ASF extends ArraySetsFactory[A] {
def equal: Equal[A] = equalI
implicit def arrayManifest: ClassManifest[A] = arrayManifestI
def emptySet: ArraySet[A] = new EmptyArraySet[A] with ASF
def one(a: A): ArraySet[A] = new ArraySetOne[A] with ASF {
val one = a
}
def two(a: A, b: A): ArraySet[A] = new ArraySetTwo[A] with ASF {
val one = a
val two = b
}
def three(a: A, b: A, c: A): ArraySet[A] = new ArraySetThree[A] with ASF {
val one = a
val two = b
val three = c
}
def four(a: A, b: A, c: A, d: A): ArraySet[A] = new ArraySetFour[A] with ASF {
val one = a
val two = b
val three = c
val four = d
}
def five(a: A, b: A, c: A, d: A, e: A): ArraySet[A] = new ArraySetFive[A] with ASF {
val one = a
val two = b
val three = c
val four = d
val five = e
}
def more(allTheAs: Array[A]): ArraySet[A] = new ArraySetArray[A] with ASF {
val ar = allTheAs
}
}
class ASFI extends ASF
new ASFI()
}
}
trait ArraySet[A] extends Iterable[A] {
def ++( other : Traversable[A] ): ArraySet[A] = other.foldLeft(this)(_ + _)
def --( other : Traversable[A] ): ArraySet[A] = other.foldLeft(this)(_ - _)
def --[B,C]( other : Traversable[B] )(implicit equiv: Equiv[C], viewA: A => C, viewB: B => C) = other.foldLeft(this)(_ - _)
def contains[B,C]( b : B )(implicit equiv: Equiv[C], viewA: A => C, viewB: B => C): Boolean
def apply[B,C]( b : B )(implicit equiv: Equiv[C], viewA: A => C, viewB: B => C): Option[A]
def + (elem: A): ArraySet[A]
def - (elem: A): ArraySet[A]
def -[B,C]( b : B )(implicit equiv: Equiv[C], viewA: A => C, viewB: B => C) : ArraySet[A]
def empty: Boolean
def size: Int
}